import fs from 'fs';
import path from 'path';
import { promisify } from 'util';

const mkdirAsync = promisify(fs.mkdir);
const writeFileAsync = promisify(fs.writeFile);

export class WriteFileTool {
  private staticDir = 'static/static'; // 静态目录路径
  private fileName = 'example.txt'; // 文件名
  private static instance: WriteFileTool;
  private constructor(staticDir?: string, fileName?: string) {
    if (staticDir) {
      this.staticDir = staticDir;
    }
    if (fileName) {
      this.fileName = fileName;
    }
    this.makeDirSync();
  }

  public static ins() {
    if (!this.instance)
      this.instance = new WriteFileTool()
    return this.instance
  }

  public async writeTextFile(text: string, fileName?: string) {
    const filePath = path.join(this.staticDir, fileName ?? this.fileName); // 文件路径
    try {
      await writeFileAsync(filePath, text);
      // console.log('文件写入成功');
    } catch (err) {
      console.error('写入文件时发生错误:', err);
      throw err; // 重新抛出错误，以便调用者可以处理
    }
  }

  //接收到bese64字符串将其转为图片写入目录中
  public async writeImageFile(base64: string, fileName?: string) {
    const filePath = path.join(this.staticDir, fileName ?? this.fileName); // 使用空值合并操作符简化代码
    // 验证base64字符串格式
    // if (!/^data:image\/\w+;base64,/.test(base64)) {
    //   throw new Error('无效的Base64字符串格式');
    // }
    const base64Data = base64.replace(/^data:image\/\w+;base64,/, '');
    const dataBuffer = Buffer.from(base64Data, 'base64');
    try {
      await writeFileAsync(filePath, dataBuffer);
      // console.log('文件写入成功');
    } catch (err) {
      console.error('写入文件时发生错误:', err);
      throw err; // 重新抛出错误，以便调用者可以处理
    }
  }
  // 判断文件目录是否存在（改为同步方法）
  makeDirSync() {
    if (!fs.existsSync(this.staticDir)) {
      console.log('目录不存在，正在创建');
      try {
        fs.mkdirSync(this.staticDir, { recursive: true });
      } catch (err) {
        console.error('创建目录时发生错误:', err);
        throw err; // 重新抛出错误，以便调用者可以处理
      }
    }
  }

  // 读取指定目录下的图片文件并转为base64字符串返回
  public async readImageFile(dir?: string, fileName?: string) {
    const filePath = path.join(dir ?? this.staticDir, fileName ?? this.fileName); // 使用空值合并操作符简化代码
    try {
      // 读取文件内容
      const dataBuffer = await fs.promises.readFile(filePath);
      return `data:image/png;base64,${dataBuffer.toString('base64')}`;
    } catch (err) {
      console.error('读取文件时发生错误:', err);
      throw err; // 重新抛出错误，以便调用者可以处理
    }
  }

  // 读取指定目录下的文件内容并返回
  public async readTextFile(dir?: string, fileName?: string) {
    const filePath = path.join(dir ?? this.staticDir, fileName ?? this.fileName); // 使用空值合并操作符简化代码
    try {
      // 读取文件内容
      return await fs.promises.readFile(filePath, 'utf-8');
    } catch (err) {
      console.error('读取文件时发生错误:', err);
      throw err; // 重新抛出错误，以便调用者可以处理
    }
  }


  // 新增方法：将字节数组写入文件
  public async writeBytesFile(bytes: Uint8Array, fileName?: string) {
    const filePath = path.join(this.staticDir, fileName ?? this.fileName);
    const dataBuffer = Buffer.from(bytes); // 确保数据是 Buffer 实例
    try {
      await writeFileAsync(filePath, dataBuffer);
      // console.log('文件写入成功');
    } catch (err) {
      console.error('写入文件时发生错误:', err);
      throw err; // 重新抛出错误，以便调用者可以处理
    }
  }

}
/**
 * 删除指定路径的图片文件
 * @param relativePath 相对路径
 * @param fileName 文件名
 */
export function deleteImageFile(relativePath: string, fileName?: string): void {
  // 获取图片文件的绝对路径
  const absolutePath = fileName == null ? path.resolve(relativePath) : path.resolve(relativePath, fileName);
  // 检查文件是否存在
  if (fs.existsSync(absolutePath)) {
    // 删除文件
    fs.unlinkSync(absolutePath);
    console.log(`已删除图片文件：${absolutePath}`);
  } else {
    console.log(`图片文件不存在：${absolutePath}`);
  }
}
/**
 * 移动文件
 * @param sourcePath 源文件路径
 * @param destinationPath 目标文件路径
 */
function moveFile(sourcePath: string, destinationPath: string): void {
  // 检查源文件是否存在
  if (fs.existsSync(sourcePath)) {
    // 移动文件
    fs.renameSync(sourcePath, destinationPath);
    console.log(`已将文件从 ${sourcePath} 移动到 ${destinationPath}`);
  } else {
    console.log(`源文件不存在：${sourcePath}`);
  }
}
// 示例用法
// deleteImageFile('./static/b4b1aca7dd7047ef8c48739ff41d1e2e copy 2.jpeg');
// 示例用法
// moveFile('static/b4b1aca7dd7047ef8c48739ff41d1e2e copy.jpeg', './src/utils/copy2.png');
export function getExtensionFromContentType(contentType: string): string {
  switch (contentType) {
    case 'image/jpeg':
      return '.jpg';
    case 'image/png':
      return '.png';
    case 'image/gif':
      return '.gif';
    case 'image/bmp':
      return '.bmp';
    case 'image/webp':
      return '.webp';
    case 'image/svg+xml':
      return '.svg';
    case 'image/tiff':
      return '.tiff';
    case 'image/x-icon':
      return '.ico';
    case 'application/pdf':
      return '.pdf';
    case 'application/msword':
      return '.doc';
    case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
      return '.docx';
    case 'application/vnd.ms-excel':
      return '.xls';
    case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
      return '.xlsx';
    case 'application/vnd.ms-powerpoint':
      return '.ppt';
    case 'application/vnd.openxmlformats-officedocument.presentationml.presentation':
      return '.pptx';
    case 'text/plain':
      return '.txt';
    case 'text/html':
      return '.html';
    case 'application/json':
      return '.json';
    case 'application/zip':
      return '.zip';
    case 'application/x-rar-compressed':
      return '.rar';
    case 'audio/mpeg':
      return '.mp3';
    case 'audio/wav':
      return '.wav';
    case 'video/mp4':
      return '.mp4';
    case 'video/x-msvideo':
      return '.avi';
    // 添加其他需要的 MIME 类型
    default:
      return '.bin'; // 默认返回 'bin' 扩展名
  }
}